home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / xlib06p2 / xcbitmap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-23  |  11.1 KB  |  291 lines

  1. #include "xbmtools.h"
  2. #include "xcbitmap.h"
  3. #include "xlib_all.h"
  4.  
  5. /* these are here instead of the header file because they're not part
  6.    of the library interface */
  7.  
  8. // rol al,1
  9. #define ROL_AL          0xc0d0
  10. // mov [esi + disp8], imm8
  11. #define SHORT_STORE_8   0x46c6
  12. // mov [esi + disp32], imm8
  13. #define STORE_8         0x86c6
  14. // mov [esi + disp8], imm16
  15. #define SHORT_STORE_32  0x46c7
  16. // mov [esi + disp32], imm16
  17. #define STORE_32        0x86c7
  18. // adc esi, imm8
  19. #define ADC_SI_IMMED    0xd683
  20. // out dx, al
  21. #define OUT_AL          0xee
  22. // ret
  23. #define RETURN          0xc3
  24. // 16-bit prefix
  25. #define WORD_PREFIX    0x66
  26.  
  27.  
  28.  
  29. int output_used = 0;
  30.  
  31.  
  32.  
  33. BYTE ColumnMask[]= { 0x11,0x22,0x44,0x88 };
  34.  
  35. /*
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37. ; _x_put_cbitmap
  38. ;
  39. ; Displays a compiled bitmap generated by x_compile_bitmap at given
  40. ; coordinates, on a given screen page.
  41. ;
  42. ; C near-callable as:
  43. ; void x_put_cbitmap (int XPos, int YPos,
  44. ;                     unsigned int PageOffset, char far * Sprite);
  45. ; ax, bx, cx, and dx are squashed like insignificant insects.
  46. */
  47.  
  48. extern void asm_x_put_cbitmap(WORD XPos, WORD YPos, WORD PageOffset, char * Sprite);
  49.  
  50. #pragma aux asm_x_put_cbitmap=  \
  51.         "push esi"              \
  52.                                 \
  53.         "mov edx, [ScrnLogicalByteWidth]"       \
  54.         "mul edx"               \
  55.         "and ebx, 0x0ffff"      \
  56.         "mov esi, ebx"          \
  57.         "sar esi, 2"            \
  58.         "and eax, 0x0ffff"      \
  59.         "add esi, eax"          \
  60.         "and ecx, 0x0ffff"      \
  61.         "add esi, ecx"          \
  62.         "add esi, 128"          \
  63.         "add esi, 0xa0000"      \
  64.                                 \
  65.         "and ebx, 3"            \
  66.         "mov ah, ColumnMask[ebx]"       \
  67.                                 \
  68.         "mov dx, 0x3c4"         \
  69.         "mov al, 0x02"          \
  70.         "out dx, ax"            \
  71.         "inc dx"                \
  72.         "mov al, ah"            \
  73.                                 \
  74.         "call edi"              \
  75.                                 \
  76.         "pop esi"               \
  77.         parm [bx] [ax] [cx] [edi]       \
  78.         modify [edx];
  79.  
  80.  
  81. // if asm_x_put_cbitmap was called directly from outside code, the compiler
  82. // couldn't find the function
  83. void x_put_cbitmap(
  84.   xScreenCoord_t XPos, 
  85.   xScreenCoord_t YPos, 
  86.   xPageHandle_t PageOffset, 
  87.   char * Sprite
  88. )
  89. {
  90.     asm_x_put_cbitmap(XPos,YPos,PageOffset,Sprite);
  91. }
  92.  
  93.  
  94. // converted these to functions because otherwise the compiler optimized code
  95. // too well, having some bad/buggy side-effects in x_compile_bitmap
  96. void Emitb(char * output, BYTE x)
  97. {
  98.     *(output + output_used) = x;
  99.     output_used++;
  100. }
  101.  
  102. void Emitw(char * output, WORD x)
  103. {
  104.     *(output + output_used) = x & 255;
  105.     *(output + output_used+1) = x >> 8;
  106.     output_used += 2;
  107. }
  108.  
  109. // emit double word
  110. void Emitd(char * output, unsigned long x)
  111. {
  112.     *(output + output_used) = x & 255;
  113.     *(output + output_used+1) = x >> 8;  
  114.     *(output + output_used+2) = x >> 16; 
  115.     *(output + output_used+3) = x >> 24;
  116.     output_used += 4;
  117. }
  118.  
  119. int x_compile_bitmap (int logical_screen_width, char * bitmap, char * output)
  120. {
  121.         long pos;
  122.         int pix0, pix1, pix2, pix3, numpix;
  123.         int column = 0, set_column = 0;
  124.         int scanx = 0, scany = 0;
  125.  
  126.         int height = LBMHeight(bitmap);
  127.         int width = LBMWidth(bitmap);
  128.         int margin = width - 1;
  129.         int margin2 = margin - 4;
  130.         int margin4 = margin - 12;
  131.  
  132.         output_used = 0;                // must reset this on every compile
  133.  
  134.         while (column < 4) {
  135.                 numpix = 1;
  136.                 pix0 = LBMGetPix(scanx, scany, bitmap);
  137.                 if (pix0 != 0) {
  138.                         if (set_column != column) {
  139.                                 do {
  140.                                         Emitw (output, ROL_AL);
  141.                                         Emitw (output, ADC_SI_IMMED);
  142.                                         Emitb (output, 0);
  143.                                         set_column++;
  144.                                 } while (set_column != column);
  145.                                 Emitb (output, OUT_AL);
  146.                         }
  147.                         if (scanx <= margin2) {
  148.                                 pix1 = LBMGetPix(scanx + 4, scany, bitmap);
  149.                                 if ((pix1 != 0)
  150.                                   &&(scanx <= margin4)) {
  151.                                         numpix = 2;
  152.                                         pix2 = LBMGetPix(scanx + 8, scany, bitmap);
  153.                                         pix3 = LBMGetPix(scanx + 12, scany, bitmap);
  154.                                         if ((pix2 != 0) && (pix3 != 0)) {
  155.                                                 numpix = 4;
  156.                                         }
  157.                                 }
  158.                         }
  159.                         pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
  160.                         if ((pos >= -128) && (pos <= 127)) {
  161.                                 if (numpix == 1) {
  162.                                         Emitw (output, SHORT_STORE_8);
  163.                                         Emitb (output, pos);
  164.                                         Emitb (output, pix0);
  165.                                 } else {
  166.                                         if( numpix != 4 )
  167.                                             Emitb (output, WORD_PREFIX);
  168.                                         Emitw (output, SHORT_STORE_32);
  169.                                         Emitb (output, pos);
  170.                                         Emitb (output, pix0);
  171.                                         Emitb (output, pix1);
  172.                                         if (numpix == 4) {
  173.                                                 Emitb (output, pix2);
  174.                                                 Emitb (output, pix3);
  175.                                         }
  176.                                 }
  177.                         } else {
  178.                                 if (numpix == 1) {
  179.                                         Emitw (output, STORE_8);
  180.                                         Emitd (output, pos);
  181.                                         Emitb (output, pix0);
  182.                                 } else {
  183.                                         if( numpix != 4 )
  184.                                             Emitb (output, WORD_PREFIX);
  185.                                         Emitw (output, STORE_32);
  186.                                         Emitd (output, pos);
  187.                                         Emitb (output, pix0);
  188.                                         Emitb (output, pix1);
  189.                                         if (numpix == 4) {
  190.                                                 Emitb (output, pix2);
  191.                                                 Emitb (output, pix3);
  192.                                         }
  193.                                 }
  194.                         }
  195.                 }
  196.                 scanx += (numpix << 2);
  197.                 if (scanx > margin) {
  198.                         scanx = column;
  199.                         scany++;
  200.                         if (scany == height) {
  201.                                 scany = 0;
  202.                                 column++;
  203.                                 scanx=column;   // this was missing in original
  204.                                                 // and caused a bug: the first
  205.                                                 // line of bitmap was shifted
  206.                                                 // right one pixel
  207.                         }
  208.                 }
  209.         }
  210.         Emitb(output, RETURN);
  211.         return(output_used);
  212. }
  213.  
  214.  
  215. int x_sizeof_cbitmap (int logical_screen_width, char * bitmap)
  216. {
  217.         int pix0, pix1, pix2, pix3, numpix, pos;
  218.         int column = 0, set_column = 0;
  219.         int scanx = 0, scany = 0;
  220.         int output_used = 1;
  221.  
  222.         int height = LBMHeight(bitmap);
  223.         int width = LBMWidth(bitmap);
  224.         int margin = width - 1;
  225.         int margin2 = margin - 4;
  226.         int margin4 = margin - 12;
  227.  
  228.         while (column < 4) {
  229.                 numpix = 1;
  230.                 pix0 = LBMGetPix(scanx, scany, bitmap);
  231.                 if (pix0 != 0) {
  232.                         if (set_column != column) {
  233.                                 do {
  234.                                         output_used += 5;
  235.                                         set_column++;
  236.                                 } while (set_column != column);
  237.                                 output_used++;
  238.                         }
  239.                         if (scanx <= margin2) {
  240.                                 pix1 = LBMGetPix(scanx + 4, scany, bitmap);
  241.                                 if ((pix1 != 0)
  242.                                   &&(scanx <= margin4)) {
  243.                                         numpix = 2;
  244.                                         pix2 = LBMGetPix(scanx + 8, scany, bitmap);
  245.                                         pix3 = LBMGetPix(scanx + 12, scany, bitmap);
  246.                                         if ((pix2 != 0) && (pix3 != 0)) {
  247.                                                 numpix = 4;
  248.                                         }
  249.                                 }
  250.                         }
  251.                         pos = (scany * logical_screen_width) + (scanx >> 2) - 128;
  252.                         if ((pos >= -128) && (pos <= 127)) {
  253.                                 if (numpix == 1) {
  254.                                         output_used += 4;
  255.                                 } else {
  256.                                         if( numpix != 4 )
  257.                                             output_used++;
  258.                                         output_used += 5;
  259.                                         if (numpix == 4)
  260.                                                 output_used += 2;
  261.                                 }
  262.                         } else {
  263.                                 if (numpix == 1) {
  264.                                         output_used += 7;
  265.                                 } else {
  266.                                         if( numpix !=4 )
  267.                                                 output_used++;
  268.                                         output_used += 8;
  269.                                         if (numpix == 4)
  270.                                                 output_used += 2;
  271.                                 }
  272.                         }
  273.                 }
  274.                 scanx += (numpix << 2);
  275.                 if (scanx > margin) {
  276.                         scanx = column;
  277.                         scany++;
  278.                         if (scany == height) {
  279.                                 scany = 0;
  280.                                 column++;
  281.                                 scanx=column;   // this was missing in original
  282.                                                 // and caused a bug: the first
  283.                                                 // line of bitmap was shifted
  284.                                                 // right one pixel
  285.                         }
  286.                 }
  287.         }
  288.         return(output_used);
  289. }
  290.  
  291.